#include "stdafx.h"
#include "ckPSNRProcessor.h"
#include "ckMSEProcessor.h"
#include "ckRasterBand.h"

namespace ck
{
	namespace algorithm
	{
		namespace raster
		{
			PSNRProcessor::PSNRProcessor()
			{
				m_pBand1 = NULL;
				m_pBand2 = NULL;
				m_psnr = 0.0;
			}


			PSNRProcessor::~PSNRProcessor()
			{
				if (m_pBand1)
				{
					m_pBand1->Release();
					m_pBand1 = NULL;
				}

				if (m_pBand2)
				{
					m_pBand2->Release();
					m_pBand2 = NULL;
				}
			}

			RESULTCODE PSNRProcessor::Execute()
			{
				if (!m_pBand1 || !m_pBand2)
				{
					return RC_FAILURE;
				}

				z_uint32 w1, h1, w2, h2;
				w1 = m_pBand1->GetWidth();
				h1 = m_pBand1->GetHeight();
				w2 = m_pBand2->GetWidth();
				h2 = m_pBand2->GetHeight();
				if ((w1 != w2) || (h1 != h2))
				{
					return RC_FAILURE;
				}

				ck::data::ckPixelType type1, type2;
				type1 = m_pBand1->GetPixelType();
				type2 = m_pBand2->GetPixelType();
				if (type1 != type2)
				{
					return RC_FAILURE;
				}

				z_uint32 pixelSize = m_pBand1->GetPixelSize();
				z_uint32 MAXI = (z_uint32)pow(2, (pixelSize << 3)) - 1;

				RESULTCODE rc;
				MSEProcessor msep;
				msep.SetBand(m_pBand1, m_pBand2);
				rc = msep.Execute();
				if (rc != RC_SUCCESS)
				{
					return rc;
				}
				double mse = msep.GetValue();

				m_psnr = 10 * log10(pow(MAXI, 2) / mse);

				return RC_SUCCESS;
			}

			void PSNRProcessor::SetBand(data::RasterBand* pBand1, data::RasterBand* pBand2)
			{
				m_pBand1 = pBand1;
				m_pBand2 = pBand2;
				if (m_pBand1)
				{
					m_pBand1->AddRef();
				}
				if (m_pBand2)
				{
					m_pBand2->AddRef();
				}
			}

			double PSNRProcessor::GetValue()
			{
				return m_psnr;
			}
		}
	}
}


